/***************************************************************************
                          expr_basic.h  -  description
                             -------------------
    begin                : Fri Jun 21 2002
    copyright            : (C) 2002 by Michiel Visser
    email                : 
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
 
#ifndef EXPR_BASIC_H
#define EXPR_BASIC_H

#include "mstl.h"
#include <vector>

using namespace Obj;
using namespace std;

namespace Expression
{


class CodeComponent;

typedef Ptr<CodeComponent>::Share EPtr;

class CodeComponent
{
public:
	virtual void iterate(void (*callback)(EPtr &e, void *param), void *param);
	virtual void evaluateToVoid() =0;
	virtual bool isExpr() const=0;
	virtual bool isContainer(bool &inARef) const;
	virtual bool consolidateSharedLiterals(vector<EPtr> &sharedLiterals, bool inARef) const;
	virtual void toArray(OList::P array) const;
	virtual void toArgumentsArray(OList::P &array) const;
	Object *toArrayObject() const;
	void toArrayObject(void *space) const; 
	Object *toArrayObject(int parentlevel) const;
	virtual void toExprArray(OList::P array) const;
	String toTyle() const;
	IFDEBUG(virtual void printTyle() const;)
	virtual bool isDynamic() const;
	virtual EPtr getPredefined() const;
	virtual bool isLValue() const;
	virtual bool isArgumentList() const;
	virtual bool isSingleResult() const;
	inline Object *evaluateToCopy();
	virtual void evaluateToCopy(void *space); // evaluate to unowned object, or unowned copy of that object, that will be owned by caller
	virtual void evaluateLiteralToCopy(void *space);
	virtual Object *evaluateLiteralToCopy();
	inline void evaluateToPersistCopy(void *space); //todo: can we get rid of this?
	inline Object *evaluateToPersistCopy(); //todo: can we get rid of this?
	virtual Object *evaluateToOriginal(); // evaluate to pointer to original object that will be shared by caller, and Garbage collected instead of deleted
	// use evaluateToCopy as much as possible, because evaluateToOriginal will create GC objects for non-variables
	// implement evaluateToOriginal as much as possible, because it is fast, but if it can create orphan objects, evaluateToCopy must be implemented as well.
	void doStackOperation(void *space, Object *var, TypeVar s);
	virtual ~CodeComponent();
	virtual int levelLeft() const;
	virtual int levelRight() const;
};

class Statement: public CodeComponent
{
	bool isExpr() const;
};

class Expr: public CodeComponent
{
public:
	bool isExpr() const;
	void evaluateToVoid();
};

typedef List<EPtr> EList;

} // namespace

#endif // FILEXXX_H
